home *** CD-ROM | disk | FTP | other *** search
Text File | 1999-01-25 | 13.1 KB | 484 lines | [TEXT/CWIE] |
- ///--------------------------------------------------------------------------------------
- // Shark Attack.c
- //
- // Created 7/25/96
- ///--------------------------------------------------------------------------------------
-
-
- #include <SWIncludes.h>
- #include <SWGameUtils.h>
- #include <SWApplication.h>
-
- #include "Application.h"
- #include "Shark Attack.h"
- #include "Level.h"
- #include "NewSprite.h"
- #include "MyUtils.h"
- #include "Special Effects.h"
- #include "Stats.h"
-
-
- #define kMaxFPS 45 // Keep the animation from going too fast
-
- #define kMaxSpriteWorldWidth 640 // Max size of the SpriteWorld. Helps avoid
- #define kMaxSpriteWorldHeight 480 // running out of memory on large monitors.
-
-
- /***********/
- /* Globals */
- /***********/
-
- SpriteWorldPtr gSpriteWorldP;
- FramePtr gStatsWindowFrameP;
- FramePtr gStatsBackFrameP;
- FramePtr gStatsNumberFrameP;
- SpriteLayerPtr gSubSpriteLayerP;
- SpriteLayerPtr gBulletSpriteLayerP;
- SpriteLayerPtr gFishSpriteLayerP;
- SpriteLayerPtr gSharkSpriteLayerP;
- WindowPtr gWindowP;
- RgnHandle gOrigWindRgn; // Original region for the window
- RgnHandle gPixPatWindRgn; // Temporary region for drawing the background pixPat
- RgnHandle gTempRgn; // Temporary region used by the FishHitDrawProc
-
- DrawProcPtr gScreenDrawProc;
- DrawProcPtr gSpriteMaskDrawProc;
- KeyStruct gKeys;
-
- PixPatHandle gBackgroundPixPatH;
- PixPatHandle gTitleWaterPixPatH;
- PicHandle gGameWaterPictH;
-
- short gFishDelay = 0;
- short gSharkDelay = 0;
- short gNumFishOnScreen = 0;
- short gNumSharksOnScreen = 0;
- SpritePtr gLastBulletP; // Pointer to the most recently shot bullet. Kept
- // so we can update the stereo sound as it moves.
- SpritePtr gSubCloneP = NULL; // Pointer to the sub sprite that is added
- // to the animation. Used by SharkSpriteMoveProc
-
- Boolean gGameOver;
- Boolean gGameIsPaused;
- long gScore;
- long gNextLevelScore; // When score equals this, advance to next level
- short gCurrentLevel;
- short gNumLivesLeft;
- short gNumShellsNeeded;
- Boolean gSubIsStillOnScreen;
-
-
- ///--------------------------------------------------------------------------------------
- // SetUpSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- void SetUpSpriteWorld( void )
- {
- Rect worldRect;
- OSErr err;
-
-
- err = SWEnterSpriteWorld();
- FatalError(err);
-
- worldRect = gWindowP->portRect;
-
- if (worldRect.right > kMaxSpriteWorldWidth)
- worldRect.right = kMaxSpriteWorldWidth;
- if (worldRect.bottom > kMaxSpriteWorldHeight)
- worldRect.bottom = kMaxSpriteWorldHeight;
-
- CenterRect(&worldRect, &gWindowP->portRect);
- err = SWCreateSpriteWorldFromWindow(&gSpriteWorldP, (CWindowPtr)gWindowP,
- &worldRect, NULL, 0);
- FatalError(err);
-
-
- // Create the sprite layers
- err = SWCreateSpriteLayer(&gSubSpriteLayerP);
- FatalError(err);
-
- err = SWCreateSpriteLayer(&gBulletSpriteLayerP);
- FatalError(err);
-
- err = SWCreateSpriteLayer(&gFishSpriteLayerP);
- FatalError(err);
-
- err = SWCreateSpriteLayer(&gSharkSpriteLayerP);
- FatalError(err);
-
- SWAddSpriteLayer(gSpriteWorldP, gFishSpriteLayerP); // Bottom layer
- SWAddSpriteLayer(gSpriteWorldP, gSharkSpriteLayerP); // Middle layer
- SWAddSpriteLayer(gSpriteWorldP, gBulletSpriteLayerP); // Middle layer
- SWAddSpriteLayer(gSpriteWorldP, gSubSpriteLayerP); // Top layer
-
- SWLockSpriteWorld(gSpriteWorldP);
-
-
- // Draw a nice background
- SWSetPortToBackground(gSpriteWorldP);
- FillCRect(&gSpriteWorldP->backRect, gTitleWaterPixPatH);
-
-
- // Set up the various drawProcs
-
- if (gSpriteWorldP->pixelDepth == 8) // If in 256 colors
- {
- gScreenDrawProc = BlitPixie8BitRectDrawProc;
- SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BlitPixie8BitRectDrawProc);
- gSpriteMaskDrawProc = CompiledSprite8BitDrawProc;
- }
- else if ( !(SW_PPC && gSpriteWorldP->pixelDepth < 8) ) // Not 256 colors
- {
- gScreenDrawProc = BlitPixieAllBitRectDrawProc;
- SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BlitPixieAllBitRectDrawProc);
- gSpriteMaskDrawProc = BlitPixieAllBitMaskDrawProc;
- }
- else
- {
- gScreenDrawProc = SWStdWorldDrawProc;
- gSpriteMaskDrawProc = SWStdSpriteDrawProc;
- }
-
- SWSetSpriteWorldMaxFPS(gSpriteWorldP, kMaxFPS);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // NewGame - called when the user selects "New Game" from the File Menu.
- ///--------------------------------------------------------------------------------------
-
- void NewGame( void )
- {
- PrepareGame();
- RunGame();
- CleanUpAfterGame();
- }
-
-
- ///--------------------------------------------------------------------------------------
- // PrepareGame
- ///--------------------------------------------------------------------------------------
-
- void PrepareGame( void )
- {
- Rect worldRect;
-
- gLastBulletP = NULL;
- gGameOver = false;
- gCurrentLevel = 1;
- gNumLivesLeft = 3;
- gNumShellsNeeded = 10;
- gScore = 0;
- gNextLevelScore = kAdvanceLevelScore;
-
- ResetStats();
- HideCursor();
- EraseMenuBar();
-
- // We can draw directly to the screen now
- SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, gScreenDrawProc);
-
- // Remove sprites from title screen animation
- RemoveAllSprites(gSpriteWorldP);
-
- // Make the SpriteWorld think it's smaller, to make room for the stats area
- worldRect = gSpriteWorldP->windRect;
- worldRect.top += kStatsHeight;
- SWChangeWorldRect(gSpriteWorldP, &worldRect, true);
-
- // Draw the game background
- FillBackgroundWithPict(gSpriteWorldP, gGameWaterPictH);
-
- SetUpLevel();
- SWUpdateSpriteWorld(gSpriteWorldP, false);
- WipeWindow(gSpriteWorldP);
-
- // Draw the stats area
- UpdateStatsArea();
- }
-
-
- ///--------------------------------------------------------------------------------------
- // EraseMenuBar - hide menu bar and draw background pixpat in its place, if necessary.
- ///--------------------------------------------------------------------------------------
-
- void EraseMenuBar( void )
- {
- RgnHandle mBarRgn;
-
- SetPort(gWindowP);
- mBarRgn = SWHideMenuBar(gWindowP);
-
- // mBarRgn = mBarRgn & gPixPatWindRgn
- SectRgn(mBarRgn, gPixPatWindRgn, mBarRgn);
-
- SetClip(mBarRgn);
- FillCRect(&gWindowP->portRect, gBackgroundPixPatH);
- SetClip(gOrigWindRgn);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // RunGame
- ///--------------------------------------------------------------------------------------
-
- void RunGame( void )
- {
- FatalError( SWStickyError() ); // Make sure no errors got past us during setup
-
- while (!gGameOver)
- {
- SWProcessSpriteWorld(gSpriteWorldP);
-
- // Check for collisions with the fish and bullets
- SWCollideSpriteLayer(gSpriteWorldP, gFishSpriteLayerP, gBulletSpriteLayerP);
- SWCollideSpriteLayer(gSpriteWorldP, gSharkSpriteLayerP, gBulletSpriteLayerP);
-
- // Make sure no errors occurred during a MoveProc, etc.
- FatalError( SWStickyError() );
-
- SWAnimateSpriteWorld(gSpriteWorldP);
-
- if (gSpriteWorldP->frameHasOccurred)
- ProcessLevel();
-
- // Check for collisions with the submarine and fish
- SWCollideSpriteLayer(gSpriteWorldP, gSubSpriteLayerP, gFishSpriteLayerP);
- SWCollideSpriteLayer(gSpriteWorldP, gSubSpriteLayerP, gSharkSpriteLayerP);
-
- UpdateKeys(); // Read any new keyUp/keyDown events
- UpdateStatsNumbers();
-
- // Time to advance the level?
- if (gScore > gNextLevelScore && gNumFishOnScreen == 0 && gNumSharksOnScreen == 0)
- AdvanceLevel();
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // CleanUpAfterGame
- ///--------------------------------------------------------------------------------------
-
- void CleanUpAfterGame( void )
- {
- // Remove any sprites that are left
- RemoveAllSprites(gSpriteWorldP);
-
- // Restore the SpriteWorld to its normal size
- SWRestoreWorldRect(gSpriteWorldP);
-
- // Draw the normal background pattern
- SWSetPortToBackground(gSpriteWorldP);
- FillCRect(&gSpriteWorldP->backRect, gTitleWaterPixPatH);
-
- AddTitleSprite();
- SWUpdateSpriteWorld(gSpriteWorldP, false);
- WipeWindow(gSpriteWorldP);
-
- // Don't draw directly to the screen during the title screen animation
- SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, SWStdWorldDrawProc);
-
- gFishDelay = 0;
- gSharkDelay = 0;
-
-
- SWShowMenuBar(gWindowP);
- ShowCursor();
- }
-
-
- ///--------------------------------------------------------------------------------------
- // RemoveAllSprites - Remove and dispose all sprites in the SpriteWorld
- ///--------------------------------------------------------------------------------------
-
- void RemoveAllSprites(SpriteWorldPtr spriteWorldP)
- {
- SpriteLayerPtr curSpriteLayerP;
- SpritePtr curSpriteP, nextSpriteP;
-
- curSpriteLayerP = spriteWorldP->headSpriteLayerP;
-
- // iterate through the layers in the world
- while (curSpriteLayerP != NULL)
- {
- curSpriteP = curSpriteLayerP->headSpriteP;
-
- // iterate through the sprites in this layer
- while (curSpriteP != NULL)
- {
- nextSpriteP = curSpriteP->nextSpriteP;
-
- SWRemoveSprite(curSpriteP);
- SWDisposeSprite(&curSpriteP);
-
- curSpriteP = nextSpriteP;
- }
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
-
- gNumFishOnScreen = 0;
- gNumSharksOnScreen = 0;
- gLastBulletP = NULL;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // PauseSprites - Pause all layers but the sub layer
- ///--------------------------------------------------------------------------------------
-
- void PauseSprites()
- {
- SWPauseSpriteLayer(gBulletSpriteLayerP);
- SWPauseSpriteLayer(gFishSpriteLayerP);
- SWPauseSpriteLayer(gSharkSpriteLayerP);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // UnpauseSprites - unpause all layers but the sub layer
- ///--------------------------------------------------------------------------------------
-
- void UnpauseSprites()
- {
- SWUnpauseSpriteLayer(gBulletSpriteLayerP);
- SWUnpauseSpriteLayer(gFishSpriteLayerP);
- SWUnpauseSpriteLayer(gSharkSpriteLayerP);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // CountNumSpritesOnScreen - returns how many Sprites are currently on the screen
- ///--------------------------------------------------------------------------------------
-
- short CountNumSpritesOnScreen(SpriteWorldPtr spriteWorldP)
- {
- SpriteLayerPtr curSpriteLayerP;
- short numSprites = 0;
-
- curSpriteLayerP = spriteWorldP->headSpriteLayerP;
-
- // iterate through the layers in the world
- while (curSpriteLayerP != NULL)
- {
- numSprites += SWCountNumSpritesInLayer(curSpriteLayerP);
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
-
- return numSprites;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // UpdateKeys (Put the latest key values in the gKeys structure)
- ///--------------------------------------------------------------------------------------
-
- void UpdateKeys( void )
- {
- EventRecord event;
- short theChar;
-
- do
- {
- GetOSEvent( (keyUpMask | keyDownMask), &event );
- ProcessKeyEvent(&event);
-
- // Check for shift key
- if (event.modifiers & shiftKey)
- gKeys.shift = true;
- else
- gKeys.shift = false;
-
- // Check for Command key combinations
- if ((event.modifiers & cmdKey) && (event.what == keyDown))
- {
- theChar = event.message & charCodeMask;
-
- if (theChar == 'p')
- PauseGame();
- else if (theChar == 'e')
- gGameOver = true;
- else if (theChar == 'q')
- ExitSharkAttack();
- }
-
- } while (event.what != nullEvent);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // ProcessKeyEvent
- ///--------------------------------------------------------------------------------------
-
- void ProcessKeyEvent( EventRecord *eventP )
- {
- short theKey;
- Boolean keyState;
-
- if (eventP->what == keyUp || eventP->what == keyDown)
- {
- theKey = (eventP->message & keyCodeMask) >> 8;
- keyState = (eventP->what == keyDown);
-
- if ( (theKey == kLeftArrowKey) || (theKey == kLeftKeyPad) )
- gKeys.left = keyState;
- if ( (theKey == kRightArrowKey) || (theKey == kRightKeyPad) )
- gKeys.right = keyState;
- if ( (theKey == kDownArrowKey) || (theKey == kDownKeyPad) )
- gKeys.down = keyState;
- if ( (theKey == kUpArrowKey) || (theKey == kUpKeyPad) )
- gKeys.up = keyState;
- if (theKey == kShootKeyPad)
- gKeys.shoot = keyState;
- if (theKey == kEscKey && eventP->what == keyDown)
- gGameOver = true;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // PauseGame
- ///--------------------------------------------------------------------------------------
-
- void PauseGame( void )
- {
- MenuHandle fileMenuH;
-
- fileMenuH = GetMenuHandle(mFile);
- CheckItem(fileMenuH, iPauseGame, true);
- EnableItem(fileMenuH, iPauseGame);
- EnableItem(fileMenuH, iEndGame);
- DisableItem(fileMenuH, iNewGame);
-
- SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, SWStdWorldDrawProc);
- SWSetPortToWorkArea(gSpriteWorldP);
- ForeColor(redColor);
- DrawTextInWorkArea("\pPaused", 64);
- SWUpdateWindow(gSpriteWorldP);
-
- HiliteMenu( 0 );
- SWShowMenuBar(gWindowP);
- ShowCursor();
-
- gGameIsPaused = true;
-
- while (gGameIsPaused)
- ProcessEvents();
-
- CheckItem(fileMenuH, iPauseGame, false);
- DisableItem(fileMenuH, iPauseGame);
- DisableItem(fileMenuH, iEndGame);
- EnableItem(fileMenuH, iNewGame);
-
- EraseMenuBar();
- HideCursor();
- UpdateStatsArea();
- SWUpdateSpriteWorld(gSpriteWorldP, true);
- SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, gScreenDrawProc);
- }
-
-
-